import { app, BrowserWindow, protocol, ipcMain, Menu, Tray,globalShortcut } from "electron";
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import path from 'path'
const platformType = { win32: false, darwin: false, linux: false }
platformType[process.platform] = true

// logo区域:
const logoMap = {
	win32: 'logo_256x256.ico',
	darwin: 'logo_256x256.icns',
	linux: 'logo_256x256.png',
}


/** 是否为开发环境 */
const isDevEnv = !app.isPackaged
/** 静态资源目录 */
const appDirPath = path.resolve(__dirname, '..')
const staticDirPath = path.resolve(appDirPath, 'static')
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
	{ scheme: 'app', privileges: { secure: true, standard: true } },
])
// 开发和线上路劲不同的问题
const winLogo = isDevEnv
	? path.join(staticDirPath, 'icons', logoMap[process.platform])
	: path.join(appDirPath, './icons/logo_256x256.ico')


export const windowsCfg = {
    id: '', //唯一id
    title: '', //窗口标题
    width: '', //宽度
    height: '', //高度
    minWidth: '', //最小宽度
    minHeight: '', //最小高度
    route: '', // 页面路由URL '/manage?id=123'
    resizable: true, //是否支持调整窗口大小
    maximize: false, //是否最大化
    backgroundColor:'#eee', //窗口背景色
    data: null, //数据
    isMultiWindow: false, //是否支持多开窗口 (如果为false，当窗体存在，再次创建不会新建一个窗体 只focus显示即可，，如果为true，即使窗体存在，也可以新建一个)
    isMainWin: false, //是否主窗口(当为true时会替代当前主窗口)
    parentId: '', //父窗口id  创建父子窗口 -- 子窗口永远显示在父窗口顶部 【父窗口可以操作】
    modal: false, //模态窗口 -- 模态窗口是禁用父窗口的子窗口，创建模态窗口必须设置 parent 和 modal 选项 【父窗口不能操作】
}

/**
 * 窗口配置
 */
export class Window {
    constructor() {
        this.main = null; //当前页
        this.group = {}; //窗口组
        this.tray = null; //托盘
        this.appTitle = '石锛锛';/** 应用标题 */
        this.customWindow = {} // 自定义外部窗口
    }
    // 窗口配置
    winOpts(wh=[]) {
        return {
            icon:winLogo,
            width: wh[0],
            height: wh[1],
            backgroundColor: '#000',
            autoHideMenuBar: true,
            titleBarStyle: "hidden",
            resizable: true,
            minimizable: true,
            maximizable: true,
            frame: false,
            show: false,
            webPreferences: {
                contextIsolation: false, //上下文隔离
                // nodeIntegration: true, //启用Node集成（是否完整的支持 node）
                nodeIntegration: true,
                devTools: true,
                webSecurity: false,
                enableRemoteModule: true, //是否启用远程模块（即在渲染进程页面使用remote）
            }
        }
    }
    // 获取窗口
    getWindow(id) {
        return BrowserWindow.fromId(id)
    }
    // 获取全部窗口
    getAllWindows() {
        return BrowserWindow.getAllWindows()
    }
    // 创建窗口
    async createWindows(options) {
        console.log('------------开始创建窗口...')
        console.log(options)
        let args = Object.assign({}, windowsCfg, options)
        console.log(args)
        // 判断窗口是否存在
        for(let i in this.group) {
            if(this.getWindow(Number(i)) && this.group[i].route === args.route && !this.group[i].isMultiWindow) {
                this.getWindow(Number(i)).focus()
                return
            }
        }
        let opt = this.winOpts([args.width || 350, args.height || 450])
        if(args.parentId) {
            console.log('parentId：' + args.parentId)
            opt.parent = this.getWindow(args.parentId)
        } else if(this.main) {
            console.log(666)
        }
        if(typeof args.modal === 'boolean') opt.modal = args.modal
        if(typeof args.resizable === 'boolean') opt.resizable = args.resizable
        if(args.backgroundColor) opt.backgroundColor = args.backgroundColor
        if(args.minWidth) opt.minWidth = args.minWidth
        if(args.minHeight) opt.minHeight = args.minHeight
        let win = new BrowserWindow(opt)
        console.log('窗口id：' + win.id)
        this.group[win.id] = {
            route: args.route,
            isMultiWindow: args.isMultiWindow,
            isMainWin:args.isMainWin
        }
        // 是否最大化
        if(args.maximize && args.resizable) {
            win.maximize()
        }
        // 是否主窗口
        if(args.isMainWin) {
            if(this.main) {
                console.log('主窗口存在')
                delete this.group[this.main.id]
                this.main.close()
            }
            this.main = win
        }
        // args.id = win.id
        win.on('close', () => win.setOpacity(0))

        // 打开网址（加载页面）
        /**
         * 开发环境: http://localhost:8848
         * 正式环境: app://./index.html
         */
        let winURL
        console.log(process.env.WEBPACK_DEV_SERVER_URL);
        if (process.env.WEBPACK_DEV_SERVER_URL) {
            // Load the url of the dev server if in development mode
            winURL = args.route ? `${process.env.WEBPACK_DEV_SERVER_URL}#${args.route}` : `${process.env.WEBPACK_DEV_SERVER_URL}#/`
            // 打开开发者调试工具
            // if (!process.env.IS_TEST) win.webContents.openDevTools()
        } else {
            createProtocol('app')
            // Load the index.html when not in development
            winURL = args.route ? `app://./index.html/#${args.route}` : `app://./index.html`
        }
        await win.loadURL(winURL)
        win.show()
        win.on('ready-to-show', () => {
            win.show()
        })
        // 屏蔽窗口菜单（-webkit-app-region: drag）
        win.hookWindowMessage(278, function(e){
            win.setEnabled(false)
            setTimeout(() => {
                win.setEnabled(true)
            }, 100)

            return true
        })
        this.everyWindowListen()
    }
    // 显示主窗口
    showMainWindow(){
        for(let i in this.group){
            if (this.group[i]['isMainWin']) {
                this.getWindow(Number(i)).show()
                this.getWindow(Number(i)).center()
                this.getWindow(Number(i)).focus()
            }
        }
    }
    // 关闭所有窗口
    closeAllWindow() {
        for(let i in this.group) {
            if(this.group[i]) {
                if(this.getWindow(Number(i))) {
                    this.getWindow(Number(i)).close()
                } else {
                    console.log('---------------------------')
                    app.quit()
                }
            }
        }
    }
    // 创建托盘
    createTray() {
        console.log('创建托盘')
        const contextMenu = Menu.buildFromTemplate([
            {
                label: '显示',
                click: () => {
                    for(let i in this.group) {
                        if(this.group[i]) {
                            // this.getWindow(Number(i)).show()
                            let win = this.getWindow(Number(i))
                            if(!win) return
                            if(win.isMinimized()) win.restore()
                            win.show()
                        }
                    }
                }
            }, 
            {
                label: '控制台',
                visible: isDevEnv,
                click: () => {
                    for(let i in this.group){
                        if(this.group[i]) {
                            this.getWindow(Number(i)).webContents.openDevTools()
                        }
                    }
                }
            },
            {
                label: '退出',
                click: () => {
                    app.quit()
                }
            }
        ])
        this.tray = new Tray(winLogo)
        this.tray.setContextMenu(contextMenu)
        this.tray.setToolTip(this.appTitle)
        /** 双击图标打开窗口 */
		this.tray.on('double-click', ()=>this.showMainWindow())
    }
    // 处理path外部链接的打开
    createCustomWindow(url){
        console.log('url', url)
        if (this.customWindow[url] && !this.customWindow[url].isDestroyed()) {
            // 如果该 URL 的窗口已存在，则将其带到前台并返回
            this.customWindow[url].show()
            return
        }
        this.customWindow[url] = new BrowserWindow({
            width: 750,
            height: 500,
            autoHideMenuBar: true, // 自动隐藏菜单栏, 除非按了Alt键, 默认值为 false
            icon: winLogo,
            // frame: false, // 隐藏标题栏
            webPreferences: {
                devTools: true, // 是否开启 DevTools, 如果设置为 false, 则无法使用 BrowserWindow.webContents.openDevTools()。 默认值为 true
                nodeIntegration: true, // 是否启用Node集成
            },
        })
        // 当链接内部的页面导航完成后，您可以重新设置自定义标题。
        // customWindow[url].webContents.on('did-navigate-in-page', (event, url) => {
        //   customWindow[url].setTitle('Custom Window Title');
        // });
        // 可以尝试使用 dom-ready 事件，它会在页面 DOM 加载完成后触发。
        // 请注意，dom-ready 事件可能在 did-navigate-in-page 事件之前触发
        // customWindow[url].webContents.on('dom-ready', () => {
        //   customWindow[url].setTitle('Custom Window Title');
        // });
        // 加载链接的内容
        this.customWindow[url].loadURL(url)
        // 可以根据需要设置自定义窗口的样式、大小等
        // 例如，customWindow.setResizable(false) 可以禁止窗口调整大小
        // 可以在自定义窗口中使用各种 Electron API 进行交互和操作
        // 在自定义窗口关闭时，释放窗口资源
        this.customWindow[url].on('closed', () => {
            delete this.customWindow[url]
        })
    }
    // 监听每个窗口
    everyWindowListen() {
        // 注册快捷键
        globalShortcut.register('CommandOrControl+L', () => {
            for(let i in this.group){
                if(this.group[i]) {
                    this.getWindow(Number(i)).webContents.openDevTools()
                }
            }
        })

        for(let i in this.group){
            if(this.group[i]) {
                this.getWindow(Number(i)).on('maximize', () => {
                    console.log(this.group);
                    this.getWindow(Number(i)).webContents.send('message-from-main',false)
                })
                this.getWindow(Number(i)).on('unmaximize', () => {
                    this.getWindow(Number(i)).webContents.send('message-from-main',true)
                })
                this.getWindow(Number(i)).webContents.setWindowOpenHandler(details => {
                    this.createCustomWindow(details.url) // 创建自定义窗口并加载链接的内容
                    // return { action: 'deny' }// 阻止打开新窗口
                })
            }
        }
    }
    // 开启监听
    listen() {
        ipcMain.on('sendData', (event, route,sendData) => {
            for(let i in this.group){
                if(this.group[i]) {
                    if(this.group[i].route === route) {
                        this.getWindow(Number(i)).webContents.send('sendDataToOther',sendData)
                    }
                }
            }
        })
        ipcMain.on('logData', (event, logData) => {
            console.log('logData',logData);
        })
        // 关闭
        ipcMain.on('window-closed', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).close()
                if(this.group[Number(winId)]) delete this.group[Number(winId)]
            } else {
                this.closeAllWindow()
            }
        })

        // 隐藏
        ipcMain.on('window-hide', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).hide()
            } else {
                for(let i in this.group) if(this.group[i]) this.getWindow(Number(i)).hide()
            }
        })

        // 显示
        ipcMain.on('window-show', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).show()
            } else {
                for(let i in this.group) if(this.group[i]) this.getWindow(Number(i)).show()
            }
        })

        // 最小化
        ipcMain.on('window-mini', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).minimize()
            } else {
                for(let i in this.group) if(this.group[i]) this.getWindow(Number(i)).minimize()
            }
        })

        // 最大化
        ipcMain.on('window-max', (event, winId) => {
            if(winId) {
                if (this.getWindow(Number(winId)).isMaximized()) {
                    this.getWindow(Number(winId)).restore() // 如果窗口已经放大，恢复原始尺寸
                } else {
                    this.getWindow(Number(winId)).maximize() // 如果窗口未放大，调用放大窗口方法
                }
            } else {
                for (let i in this.group) {
                    if(this.group[i]){
                        if (this.getWindow(Number(i)).isMaximized()) {
                            this.getWindow(Number(i)).restore() // 如果窗口已经放大，恢复原始尺寸
                        } else {
                            this.getWindow(Number(i)).maximize() // 如果窗口未放大，调用放大窗口方法
                        }
                    }
                }
            }
        })

        // 最大化/最小化
        ipcMain.on('window-max-min-size', (event, winId) => {
            if(winId) {
                if(this.getWindow(winId).isMaximized()) {
                    this.getWindow(winId).unmaximize()
                }else {
                    this.getWindow(winId).maximize()
                }
            }
        })

        // 还原
        ipcMain.on('window-restore', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).restore()
            } else {
                for(let i in this.group) if(this.group[i]) this.getWindow(Number(i)).restore()
            }
        })

        // 重新加载
        ipcMain.on('window-reload', (event, winId) => {
            if(winId) {
                this.getWindow(Number(winId)).reload()
            } else {
                for(let i in this.group) if(this.group[i]) this.getWindow(Number(i)).reload()
            }
        })

        // /** 设置窗口大小 */
        ipcMain.on('set_win_size', (event, winId,params) => {
        	if (winId) {
                let winMain = this.getWindow(Number(winId))
                winMain.setResizable(params.resizable)
                // const size = adaptSizeWithScreen(params)
                if (!params.isLogin) {
                    winMain.setSize(params.width, params.height)
                    winMain.setMinimumSize(params.width, params.height) //主页面的最小尺寸
                } else {
                    winMain.setMinimumSize(params.width, params.height) //主页面的最小尺寸
                    winMain.setSize(params.width, params.height)
                }
                winMain.setMaximizable(params.maxable)
                winMain.center()
                winMain.focus()
            }
        })

        // 创建窗口
        ipcMain.on('window-new', (event, args) => this.createWindows(args))
    }
}